<?php
/**
 * 获取通道返回数据模块
 * 北京时间7月24日下午2点到6点生成美国东部时间7月23号（7月23号13：00 7月24号13：00）的数据（文件内部的时间是美国时间的数据）
 */
namespace app\controllers\crontab;
use Yii;
use app\components\Sftp;
use app\components\EmailMarket;
class GetCheetChannelReturnDataController extends \app\base\Controller
{
   
    public $config = array(
        'host'      => 'tt.cheetahmail.com',
        'user'      => 'huanqyg',
        'port'      => '22',
        'passwd'    => 'Ch33tah',
    ); 
    
    // cheet通道每天有两个文件
    //public $downLoadFileName1 = ""; 
    //public $downLoadFileName2 = ""; 
    public $dirPath = ROOT_PATH.'/bounces_data/cheet_data/'; // 下载文件保存路径
    public $beforeOneDay;
    // 从通道上返回的所有数据
    public $reachChannelDataArr = [];
    public $emailObj;
    
    
    
    /*
     * 手动删除一个月前通达返回的数据文件
     */
    
    public function actionDelChannelDataFiles()
    {
        
        \yii::$app->bjTime->date("Ymd",\yii::$app->bjTime->time());
    }
    
    /**
     * 下载文件
     */
    public function downLoadFile()
    {
       

        // 当前要下载的文件名
        // $this->downLoadFileName1 = "data_{$beforeOneDay}.dat"; 
        // $this->downLoadFileName2 = "iid_keys_{$beforeOneDay}.dat"; 
        
        if (!file_exists(ROOT_PATH.'/bounces_data') || !is_dir(ROOT_PATH.'/bounces_data')) { // 说明目录不存在
            echo ROOT_PATH.'/bounces_data 目录不存在请手动创建';
            exit;
        } else { // 创建相关文件夹
            if (!file_exists($this->dirPath)) {
                mkdir($this->dirPath);
            }
        }
        
       
      
        // 连接sftp拉取文件
        //重连5次
        $times = 0;
        while ($times < 5) {
            try {
                $handle = new Sftp($this->config, false);//使用密码访问
            } catch (Exception $e) {
                echo '第'.($times+1).'次连接错误：'.$e->getMessage();
            }
            if(isset($handle) && true === $handle->active) {
                break;
            }
            $times++;
        }
       
        // 读取远程路径
        $remote = 'fromcheetah';// 相对ftp的目录
        $fileList = $handle->getRemoteFileList($remote);
        
        
        echo "开始下载文件!<br/>";
        if (count($fileList) > 0) {
            foreach ($fileList as $curFile) {
                if(strpos($curFile, (string)$this->beforeOneDay) !== false) {
                    $newFile = $remote.'/'.$curFile;
                    $tempFile = 'yumao_'.$curFile;
                    $newLocal = $this->dirPath.$tempFile;
                    echo $newLocal . '<br/>';
                    if (!file_exists($newLocal)) {
                        copy("ssh2.sftp://{$handle->sftp}/{$remote}/" . $curFile, $newLocal);
                    } 
                } 
            }
            return true;
        } else {
            echo '<br/>服务器上相关文件还没有生成';
            exit;
        }                
    }
    /**
     * 数据抓取
     */
    public function actionGetDetailInfo()
    {
        ignore_user_abort(true); 
        set_time_limit(0);
        //$this->curBjTime = \yii::$app->bjTime->time()-24*3600;
        //$curBjTime = \yii::$app->bjTime->time();
        if (isset($_GET['curBjTime']) && $_GET['curBjTime']) {
            $curBjTime = $_GET['curBjTime'];
        } else {
            $curBjTime = \yii::$app->bjTime->time();
        }
      
        $this->beforeOneDay = \yii::$app->bjTime->date("Ymd",$curBjTime-24*3600);
//        $this->beforeOneDay = 20171020;
        // 下载文件
        /** 测试机上暂时注释 */
        $downloadResult = $this->downLoadFile();
        if (!$downloadResult) {
            echo '--文件下载失败!<br/>'; 
            exit;
        }
        echo '--文件下载成功!<br/>';
        /** 测试机上暂时注释 */
        // 处理数据
        $this->dealData();
        
        echo '--数据处理完毕!<br>';
    }
    
    public function timeDeal($timeS) {
       
        $timeT = \yii::$app->bjTime->strtotime($timeS);
        $timeT = $timeT+13*3600;
        return \yii::$app->bjTime->date('Y-m-d H:i:s',$timeT);
        
    }
    /**
     * 处理相关文件，从中获取数据
     */
    public function dealData()
    {
        $this->emailObj = new EmailMarket();
        $iidkeyArr = [];  //issueid对应组信息
        
        // 遍历目录
        $fileList = scandir($this->dirPath);
        foreach ($fileList as $curFile) {
            if (strpos($curFile, (string)$this->beforeOneDay) !== false) {
                $localCurFile = $this->dirPath.$curFile;
                echo "开始处理{$localCurFile}...<br/>";
                $reHandle = gzopen($localCurFile, 'r');
                echo $localCurFile.'<br>';
                while (!gzeof($reHandle)) {
                    $buffer = gzgets($reHandle, 4096);
                    $buffer = trim($buffer," \t\n\r\0\x0B");
                    //去掉前后所有形式的空格
                    $buffer = str_replace(array(" ","\t", "\n", "\r", "\0", "\x0B"), '#', $buffer);
                    $buffer = str_replace(array("##","###","####"), '#', $buffer);
                    if (strlen($buffer)>10) {
                        $mes = explode('#', $buffer);
                        if(strpos($mes[3], '@') !== false) {
                            if ($mes[0] == 1) {
                                $issueid = $mes[2];
                                if (!isset($this->reachChannelDataArr[$issueid])) {
                                    $this->reachChannelDataArr[$issueid] = [];
                                    $this->reachChannelDataArr[$issueid]['channel'] = 4;
                                    $this->reachChannelDataArr[$issueid]['emailSendInfo'] = [];    
                                }
                                $email = $mes[3];
                                $emailEncode =  $this->emailObj->encryption($email);
                                
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['email'] = $email;
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['emailEncode'] = $emailEncode;
                                if (empty($mes[1])) {
                                    $mes[1] = 0;
                                }
                                if ($mes[4] == 'R') { // 第五个如果是R表示发送成功,如果是S表示弹回
                                    $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['is_send_success'] = 1;
                                    $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['send_success_time'] = $mes[1];
                                } elseif ($mes[4] == 'S') {
                                    $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['is_hard_bounces'] = 1;
                                    $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['bounces_time'] = $mes[1]; 
                                }
                            } elseif ($mes[0] == 20) {
                                $issueid = $mes[2];
                                if (!isset($this->reachChannelDataArr[$issueid])) {
                                    $this->reachChannelDataArr[$issueid] = [];
                                    $this->reachChannelDataArr[$issueid]['channel'] = 4;
                                    $this->reachChannelDataArr[$issueid]['emailSendInfo'] = [];    
                                }
                                $email = $mes[3];
                                $emailEncode =  $this->emailObj->encryption($email);
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['email'] = $email;
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['emailEncode'] = $emailEncode;
                                if (empty($mes[1])) {
                                    $mes[1] = 0;
                                }
                                
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['is_click'] = 1;
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['click_time'] = $mes[1];
                            } elseif ($mes[0] == 50) {
                                // 表示退订的数据
                                $issueid = $mes[2];
                				$email = $mes[3];
                                $emailEncode =  $this->emailObj->encryption($email);
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['email'] = $email;
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['emailEncode'] = $emailEncode;
                                if (empty($mes[1])) {
                                    $mes[1] = 0;
                                }                                
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['is_unsubscribe'] = 1;
                                $this->reachChannelDataArr[$issueid]['emailSendInfo'][$emailEncode]['unsubscribe_time'] = $mes[1];   
                            }      
                        } elseif (strlen($mes[0]) > 9) { // 说明是idd_keys文件
                            $iidkeyArr[$mes[0]] = end($mes);
                        }
                    }
                } 
                gzclose($reHandle);
                // unlink($localCurFile); 压缩文件暂时不删除	
            }
        } 
        
        // 处理数据入库
        $tableName = 'mail_trace_detail';
        
       
        $curBjTime = \yii::$app->bjTime->time();
        foreach ($iidkeyArr as $iidkeyArrK => $iidkeyArrV) {
           
            $groupInfoArr = explode('_',$iidkeyArrV);
            if (count($groupInfoArr) != 6 && count($groupInfoArr) != 5) {
                continue; // 不是ems通过cheet通道返回来的相关数据
            } else {
                
              
                $gid = $groupInfoArr[0];
                // 如果我们网站没有当前分组则不统计 先注释
                $groupExistInfoSql =  "select count(*) from mail_group where group_id={$gid}";
                $groupExistInfo = Yii::$app->db->createCommand($groupExistInfoSql)->queryScalar();
                if (!$groupExistInfo) {
                    continue;
                }
                
                $channelId = 4;
               
                $valuesStr = "";
                if (isset($this->reachChannelDataArr[$iidkeyArrK]) && isset($this->reachChannelDataArr[$iidkeyArrK]['emailSendInfo'])) {
                    foreach ($this->reachChannelDataArr[$iidkeyArrK]['emailSendInfo'] as $emailSendInfoV) {
                        $insertSql = "insert into {$tableName}(channel_id,gid,email,email_type,is_send_success,send_success_time,send_success_date,is_hard_bounces,is_soft_bounces,bounces_time,bounces_date,is_complaint,complaint_time,complaint_date,is_unsubscribe,unsubscribe_time,unsubscribe_date,is_click,click_time,click_date,add_time) values " ;
                
                       
                        // 信息不存在的则补全默认信息
                        $emailType = $this->emailObj->getEmailType($emailSendInfoV['email']);// 邮箱类型
                        $email =  $emailSendInfoV['emailEncode'];// 邮箱地址
                        
                        $is_send_success = isset($emailSendInfoV['is_send_success']) ? $emailSendInfoV['is_send_success'] : 0;  // 是否发送成功
                        $send_success_time = $is_send_success && isset($emailSendInfoV['send_success_time']) ? $this->timeDeal($emailSendInfoV['send_success_time']) : 0;  // 发送成功时间
                        $send_success_date = $send_success_time ? strstr($send_success_time,' ',true) : '';
                        
                        $is_hard_bounces = isset($emailSendInfoV['is_hard_bounces']) ? $emailSendInfoV['is_hard_bounces'] : 0; // 是否硬弹
                
                        $is_soft_bounces = isset($emailSendInfoV['is_soft_bounces']) ? $emailSendInfoV['is_soft_bounces'] : 0; // 是否软弹
                        
                        $bounces_time = ($is_hard_bounces || $is_soft_bounces) && isset($emailSendInfoV['bounces_time']) ? $this->timeDeal($emailSendInfoV['bounces_time']) : 0; // 弹出时间
                        
                        $bounces_date = $bounces_time ? strstr($bounces_time,' ',true) : '';
                        
                        $is_complaint = isset($emailSendInfoV['is_complaint']) ? $emailSendInfoV['is_complaint'] : 0; // 是否投诉
                        
                        $complaint_time = $is_complaint && isset($emailSendInfoV['complaint_time']) ? $this->timeDeal($emailSendInfoV['complaint_time']) : 0; // 投诉时间
                        
                        $complaint_date = $complaint_time ? strstr($complaint_time,' ',true) : '';
                        
                        $is_unsubscribe = isset($emailSendInfoV['is_unsubscribe']) ? $emailSendInfoV['is_unsubscribe'] : 0; // 是否退订
                        
                        $unsubscribe_time = $is_unsubscribe && isset($emailSendInfoV['unsubscribe_time']) ? $this->timeDeal($emailSendInfoV['unsubscribe_time']) : 0; // 退订时间
                        
                        $unsubscribe_date = $unsubscribe_time ? strstr($unsubscribe_time,' ',true) : '';
                        
                        $is_click = isset($emailSendInfoV['is_click']) ? $emailSendInfoV['is_click'] : 0; // 是否点击
                        
                        $click_time = $is_click && isset($emailSendInfoV['click_time']) ? $this->timeDeal($emailSendInfoV['click_time']) : 0; // 点击时间
                        
                        $click_date = $click_time ? strstr($click_time,' ',true) : '';
                        //对记录做唯一性判断
                        $dataArr = array(
                            'is_send_success' => $is_send_success,
                            'send_success_time'  => $send_success_time,
                            'send_success_date'  => $send_success_date,
                            'is_hard_bounces'   => $is_hard_bounces,
                            'is_soft_bounces'   => $is_soft_bounces,
                            'bounces_time'      => $bounces_time,
                            'bounces_date'      => $bounces_date,
                            'is_complaint'      => $is_complaint,
                            'complaint_time'    => $complaint_time,
                            'complaint_date'    => $complaint_date,
                            'is_unsubscribe'    => $is_unsubscribe,
                            'unsubscribe_time'  => $unsubscribe_time,
                            'unsubscribe_date'  => $unsubscribe_date,
                            'is_click'  => $is_click,
                            'click_time'  => $click_time,
                            'click_date'  => $click_date
                        );
                        $updateData = [];
                        foreach($dataArr as $key => $data){
                            if($data){
                                $updateData[] = "$key = '$data'";
                            }
                        }
                        if(empty($updateData)){
                            continue;
                        }
                        $valuesStr = "({$channelId},{$gid},'{$email}','{$emailType}',{$is_send_success},'{$send_success_time}','{$send_success_date}',{$is_hard_bounces},{$is_soft_bounces},'{$bounces_time}','{$bounces_date}',{$is_complaint},'{$complaint_time}','{$complaint_date}',{$is_unsubscribe},'{$unsubscribe_time}','{$unsubscribe_date}',{$is_click},'{$click_time}','{$click_date}',{$curBjTime}) ON DUPLICATE KEY UPDATE is_deal=0,channel_id={$channelId},add_time='{$curBjTime}',".join(',',$updateData);  
                        
                        
                        
                        $insertSql .=$valuesStr;
                        // 入库
                        Yii::$app->db->createCommand($insertSql)->execute();
                        
                    }
                    
                } else {
                    continue;
                } 
            }
        }
    }
   
}

